package com.neolix.watch.service;

import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.IBinder;
import android.os.Looper;
import android.os.Message;

import static com.neolix.watch.service.BackgroundTaskBase.KEY_TASK_CLASS;

public class BackgroundTaskService extends Service {
    private static final String BACKGROUND_TASK_SERVICE = "BackgroundTaskService";
    private volatile Looper looper;
    private volatile TaskRunner taskRunner;

    private final class TaskRunner extends Handler {
        public TaskRunner(Looper looper) {
            super(looper);
        }

        @Override
        public void handleMessage(Message msg) {
            BackgroundTaskBase taskBase = (BackgroundTaskBase) msg.obj;

            taskBase.execute();
        }
    }

    @Override
    public void onCreate() {
        super.onCreate();

        HandlerThread thread = new HandlerThread(BACKGROUND_TASK_SERVICE);
        thread.start();

        looper = thread.getLooper();
        taskRunner = new TaskRunner(looper);
    }

    private void executeTask(BackgroundTaskBase task, int startId) {
        Message msg = taskRunner.obtainMessage();
        msg.arg1 = startId;
        msg.obj = task;

        switch (task.getPriority()) {
            case NORMAL_PRIORITY:
                taskRunner.sendMessage(msg);
                break;
            case HIGH_PRIORITY:
                taskRunner.sendMessageAtFrontOfQueue(msg);
                break;
        }
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Class taskClass = (Class) intent.getSerializableExtra(KEY_TASK_CLASS);

        try {
            BackgroundTaskBase task = (BackgroundTaskBase) taskClass.getDeclaredConstructor(Context.class)
                    .newInstance(getApplicationContext());
            executeTask(task, startId);
        } catch (Exception e) {
            e.printStackTrace();
        }

        return START_REDELIVER_INTENT;
    }

    @Override
    public void onDestroy() {
        looper.quit();
    }

    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    public static void submitTask(Context context, Class<? extends BackgroundTaskBase> taskClass) {
        Intent intent = new Intent(context, BackgroundTaskService.class);
        intent.putExtra(KEY_TASK_CLASS, taskClass);

        context.startService(intent);
    }
}